using System;
using System.Diagnostics.Contracts;
using System.Linq.Expressions;
using System.Reflection;
using System.Collections.Generic;

namespace Charisma
{
    public class EntityConfigurator
    {
        internal Dictionary<MemberInfo, EntityMemberConfigurator> Members;
        internal EntityMemberConfigurator KeyMember;
        internal Type EntityType;

        protected EntityConfigurator()
        {
            Members = new Dictionary<MemberInfo, EntityMemberConfigurator>();
        }
    }

    public class EntityConfigurator<T> : EntityConfigurator
    {
        public EntityConfigurator()
        {
            EntityType = typeof(T);
        }

        public EntityMemberConfigurator<T, TValue> Map<TValue>(Expression<Func<T, TValue>> expression)
        {
            Contract.Requires(expression != null);
            Contract.Requires<NotSupportedException>(expression.Body is MemberExpression,
                "Expressions other then 'MemberExpression' are not supported yet.");

            var member = ((MemberExpression) expression.Body).Member;
            EntityMemberConfigurator c;
            if (Members.TryGetValue(member, out c))
                return (EntityMemberConfigurator<T, TValue>)c;

            var result = new EntityMemberConfigurator<T, TValue>(this, member);
            Members[member] = result;
            return result;
        }

        public EntityConfigurator<T> HasKey<TValue>(Expression<Func<T, TValue>> expression)
        {
            KeyMember = Map(expression);
            return this;
        }


        public EntityConfigurator<T> Ignore<TValue>(Expression<Func<T, TValue>> expression)
        {
            var c = Map(expression);
            c.Ignore();
            return this;
        }
    }
}